/*
 * Academic License - for use in teaching, academic research, and meeting
 * course requirements at degree granting institutions only.  Not for
 * government, commercial, or other organizational use.
 * File: autobase.c
 *
 * MATLAB Coder version            : 3.4
 * C/C++ source code generated on  : 31-Oct-2022 18:36:01
 */

/* Include Files */
#include "rt_nonfinite.h"
#include "autobase.h"
#include "sign.h"
#include "nanmean.h"
#include "mldivide.h"
#include "nansum.h"
#include "prctile.h"
#include "autobase_rtwutil.h"

/* Variable Definitions */
static float autoRange;
static float upper;
static float lower;
static float caled;
static float countAfterCal;
static float bs_0;
static float bs_pre;
static float buf_sg[288];
static float buf_bs[432];
static float buf_er[216];
static float buf_auc[24];

/* Function Declarations */
static float rt_powf_snf(float u0, float u1);

/* Function Definitions */

/*
 * Arguments    : float u0
 *                float u1
 * Return Type  : float
 */
static float rt_powf_snf(float u0, float u1)
{
  float y;
  float f1;
  float f2;
  if (rtIsNaNF(u0) || rtIsNaNF(u1)) {
    y = ((real32_T)rtNaN);
  } else {
    f1 = (float)fabs(u0);
    f2 = (float)fabs(u1);
    if (rtIsInfF(u1)) {
      if (f1 == 1.0F) {
        y = 1.0F;
      } else if (f1 > 1.0F) {
        if (u1 > 0.0F) {
          y = ((real32_T)rtInf);
        } else {
          y = 0.0F;
        }
      } else if (u1 > 0.0F) {
        y = 0.0F;
      } else {
        y = ((real32_T)rtInf);
      }
    } else if (f2 == 0.0F) {
      y = 1.0F;
    } else if (f2 == 1.0F) {
      if (u1 > 0.0F) {
        y = u0;
      } else {
        y = 1.0F / u0;
      }
    } else if (u1 == 2.0F) {
      y = u0 * u0;
    } else if ((u1 == 0.5F) && (u0 >= 0.0F)) {
      y = (float)sqrt(u0);
    } else if ((u0 < 0.0F) && (u1 > (float)floor(u1))) {
      y = ((real32_T)rtNaN);
    } else {
      y = (float)pow(u0, u1);
    }
  }

  return y;
}

/*
 * Arguments    : float n
 *                float sg
 *                float bs0
 *                float bspre
 *                float badsg
 *                float minsg
 *                float *sg1
 *                float *b0
 *                float *bpre
 * Return Type  : void
 */
void autobase(float n, float sg, float bs0, float bspre, float badsg, float
              minsg, float *sg1, float *b0, float *bpre)
{
  float bs_00;
  float bs_upper;
  float bs_lower;
  float bs_pre0;
  int i;
  float er_mean;
  float value;
  float c;
  float bs;
  float f0;
  int trueCount;
  int i0;
  long long i1;
  static const float fv0[4] = { 1.10941063E+6F, -4449.6F, -4449.6F, 36.0F };

  float a[2];
  float p[2];
  float p1;
  int partialTrueCount;
  float bs_dif;
  static const float b_a[72] = { -333.6F, 1.0F, -321.6F, 1.0F, -309.6F, 1.0F,
    -297.6F, 1.0F, -285.6F, 1.0F, -273.6F, 1.0F, -261.6F, 1.0F, -249.6F, 1.0F,
    -237.6F, 1.0F, -225.6F, 1.0F, -213.6F, 1.0F, -201.6F, 1.0F, -189.6F, 1.0F,
    -177.6F, 1.0F, -165.6F, 1.0F, -153.6F, 1.0F, -141.6F, 1.0F, -129.6F, 1.0F,
    -117.600006F, 1.0F, -105.600006F, 1.0F, -93.6000061F, 1.0F, -81.6000061F,
    1.0F, -69.6000061F, 1.0F, -57.6000061F, 1.0F, -45.6000061F, 1.0F,
    -33.6000061F, 1.0F, -21.6000061F, 1.0F, -9.6000061F, 1.0F, 2.3999939F, 1.0F,
    14.3999939F, 1.0F, 26.3999939F, 1.0F, 38.3999939F, 1.0F, 50.3999939F, 1.0F,
    62.3999939F, 1.0F, 74.3999939F, 1.0F, 86.3999939F, 1.0F };

  int b_trueCount;
  float er;
  int tmp_size[1];
  static const float tx[72] = { -333.6F, -321.6F, -309.6F, -297.6F, -285.6F,
    -273.6F, -261.6F, -249.6F, -237.6F, -225.6F, -213.6F, -201.6F, -189.6F,
    -177.6F, -165.6F, -153.6F, -141.6F, -129.6F, -117.600006F, -105.600006F,
    -93.6000061F, -81.6000061F, -69.6000061F, -57.6000061F, -45.6000061F,
    -33.6000061F, -21.6000061F, -9.6000061F, 2.3999939F, 14.3999939F,
    26.3999939F, 38.3999939F, 50.3999939F, 62.3999939F, 74.3999939F, 86.3999939F,
    1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F,
    1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F,
    1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F };

  short tmp_data[288];
  float b_tmp_data[288];
  float b_bs_dif;
  if (n <= 0.0F) {
    if (n < -1.0F) {
      bs_0 = ((real32_T)rtNaN);
      bs_pre = ((real32_T)rtNaN);
      autoRange = 0.0F;
      upper = 9.0F;
      lower = 4.0F;
      countAfterCal = 0.0F;
      er_mean = (sg - bs0) / buf_sg[287];
      for (i = 0; i < 288; i++) {
        buf_sg[i] = buf_sg[i] * er_mean + bs0;
      }

      for (i = 0; i < 432; i++) {
        buf_bs[i] = buf_bs[i] * er_mean + bs0;
      }

      for (i = 0; i < 216; i++) {
        buf_er[i] = ((real32_T)rtNaN);
      }
    } else {
      if (n < 0.0F) {
        caled = 1.0F;
        autoRange = 0.0F;
      } else {
        caled = 0.0F;
        autoRange = badsg;
      }

      bs_0 = bs0;
      bs_pre = bspre;
      if (rtIsNaNF(bs_0) || rtIsNaNF(bs_pre)) {
        countAfterCal = 0.0F;
      } else {
        countAfterCal = 230.0F;
      }

      upper = 9.0F;
      lower = 4.0F;
      for (i = 0; i < 288; i++) {
        buf_sg[i] = ((real32_T)rtNaN);
      }

      for (i = 0; i < 432; i++) {
        buf_bs[i] = ((real32_T)rtNaN);
      }

      for (i = 0; i < 216; i++) {
        buf_er[i] = ((real32_T)rtNaN);
      }

      for (i = 0; i < 24; i++) {
        buf_auc[i] = ((real32_T)rtNaN);
      }
    }

    *sg1 = ((real32_T)rtNaN);
    *b0 = bs_0;
    *bpre = bs_pre;
  } else {
    countAfterCal++;
    bs_00 = bs_0;
    bs_upper = ((real32_T)rtNaN);
    bs_lower = ((real32_T)rtNaN);
    bs_pre0 = bs_pre;
    for (i = 0; i < 287; i++) {
      buf_sg[i] = buf_sg[i + 1];
    }

    if ((badsg != 0.0F) || (sg < 1.0F)) {
      buf_sg[287] = ((real32_T)rtNaN);
    } else {
      buf_sg[287] = sg;
    }

    value = prctile(buf_sg);
    er_mean = b_prctile(*(float (*)[145])&buf_sg[143]);
    c = er_mean - value;
    if (!(c < 1.0F)) {
      c = 1.0F;
    }

    if (!(c > -1.0F)) {
      c = -1.0F;
    }

    bs = (value + (value + c)) / 2.0F;
    for (i = 0; i < 431; i++) {
      buf_bs[i] = buf_bs[i + 1];
    }

    buf_bs[431] = bs;
    value = nanmean(*(float (*)[173])&buf_bs[259]);
    if ((autoRange != 0.0F) && rtIsNaNF(bs_0)) {
      if (n >= 288.0F) {
        f0 = rt_roundf_snf(n / 48.0F);
        if (f0 < 2.14748365E+9F) {
          i0 = (int)f0;
        } else {
          i0 = MAX_int32_T;
        }

        i1 = i0 * 48LL;
        if (i1 > 2147483647LL) {
          i1 = 2147483647LL;
        } else {
          if (i1 < -2147483648LL) {
            i1 = -2147483648LL;
          }
        }

        if ((double)n == (int)i1) {
          for (i = 0; i < 23; i++) {
            buf_auc[i] = buf_auc[i + 1];
          }

          trueCount = 0;
          for (i = 0; i < 288; i++) {
            if (!rtIsNaNF(buf_sg[i])) {
              trueCount++;
            }
          }

          if (trueCount > 259.199982F) {
            b_trueCount = 0;
            for (i = 0; i < 288; i++) {
              if (buf_sg[i] > bs) {
                b_trueCount++;
              }
            }

            partialTrueCount = 0;
            for (i = 0; i < 288; i++) {
              if (buf_sg[i] > bs) {
                tmp_data[partialTrueCount] = (short)(i + 1);
                partialTrueCount++;
              }
            }

            tmp_size[0] = b_trueCount;
            for (i0 = 0; i0 < b_trueCount; i0++) {
              b_tmp_data[i0] = buf_sg[tmp_data[i0] - 1] - bs;
            }

            er_mean = nansum(b_tmp_data, tmp_size);
            buf_auc[23] = er_mean / (float)trueCount;
          } else {
            buf_auc[23] = ((real32_T)rtNaN);
          }
        }
      }

      trueCount = 0;
      for (i = 0; i < 24; i++) {
        if (!rtIsNaNF(buf_auc[i])) {
          trueCount++;
        }
      }

      er_mean = b_nanmean(buf_auc);
      if ((!rtIsNaNF(er_mean)) && (trueCount > 3)) {
        c = (er_mean - 0.9F) / 0.9F;
        if (!(c < 1.0F)) {
          c = 1.0F;
        }

        if (!(c > 0.0F)) {
          c = 0.0F;
        }

        er_mean = (5.1F + 3.9F * rt_powf_snf(c, 1.2F)) - upper;
        if (!(er_mean < 0.05F)) {
          er_mean = 0.05F;
        }

        if (!(er_mean > -0.05F)) {
          er_mean = -0.05F;
        }

        upper += er_mean;

        /*          auc_scale = max(min((mean_auc-1)/(2.5-1), 1), 0); */
        c = (4.6F + -0.599999905F * rt_powf_snf(c, 1.2F)) - lower;
        if (!(c < 0.05F)) {
          c = 0.05F;
        }

        if (!(c > -0.05F)) {
          c = -0.05F;
        }

        lower += c;
      }
    }

    if (rtIsNaNF(bs_0)) {
      bs_00 = value;
    }

    if (rtIsNaNF(bs_pre)) {
      if (bs_00 < 9.0F) {
        bs_pre0 = bs_00;
      } else {
        bs_pre0 = 9.0F;
      }

      if (!(bs_pre0 > 4.0F)) {
        bs_pre0 = 4.0F;
      }
    }

    if (!rtIsNaNF(bs_00)) {
      if (bs_00 > upper) {
        bs_00 = upper;
        bs_upper = upper;
      }

      if (bs_00 < lower) {
        bs_00 = lower;
        bs_lower = lower;
      }
    }

    for (i0 = 0; i0 < 2; i0++) {
      a[i0] = 0.0F;
      for (partialTrueCount = 0; partialTrueCount < 36; partialTrueCount++) {
        a[i0] += b_a[i0 + (partialTrueCount << 1)] * buf_bs[11 + 12 *
          partialTrueCount];
      }
    }

    mldivide(fv0, a, p);
    p1 = p[0];
    bs_dif = p[0];
    if (!(bs_dif < 0.001F)) {
      bs_dif = 0.001F;
    }

    if (!(bs_dif > -0.01F)) {
      bs_dif = -0.01F;
    }

    p[0] = bs_dif;
    er = 0.0F;
    for (i = 0; i < 36; i++) {
      f0 = 0.0F;
      for (i0 = 0; i0 < 2; i0++) {
        f0 += tx[i + 36 * i0] * p[i0];
      }

      c = f0 - buf_bs[11 + 12 * i];
      er += c * c;
    }

    er /= 36.0F;
    if (bs_dif < 0.0F) {
      er *= 0.5F;
    } else {
      er *= 0.8F;
    }

    for (i = 0; i < 215; i++) {
      buf_er[i] = buf_er[i + 1];
    }

    buf_er[215] = er;
    c = er * 2.0F;
    if (!(c > 1.0F)) {
      c = 1.0F;
    }

    p[0] = bs_dif / c;
    er_mean = p[0];
    if (!(er_mean > -0.002F)) {
      er_mean = -0.002F;
    }

    p[0] = er_mean;
    f0 = 0.0F;
    for (i0 = 0; i0 < 2; i0++) {
      f0 += (231.4F + -230.4F * (float)i0) * p[i0];
    }

    if (!rtIsNaNF(f0)) {
      er_mean = c_nanmean(buf_er);
      if (rtIsNaNF(er_mean)) {
        er_mean = er;
      }

      if ((er > er_mean) || rtIsNaNF(er_mean)) {
      } else {
        er = er_mean;
      }

      bs_dif = 1.0F - er;
      if (!(bs_dif < 1.0F)) {
        bs_dif = 1.0F;
      }

      if (!(bs_dif > 0.0F)) {
        bs_dif = 0.0F;
      }

      if (rtIsNaNF(bs_pre0)) {
        er_mean = bs_00;
      } else {
        er_mean = bs_pre0;
      }

      if (f0 > er_mean) {
        c = rt_powf_snf(bs_dif, 8.0F);
      } else {
        c = bs_dif * bs_dif;
      }

      if (!(c > 0.01F)) {
        c = 0.01F;
      }

      c = (f0 * c + er_mean * (1.0F - c)) - er_mean;
      if (!(c < 0.005F)) {
        c = 0.005F;
      }

      if (!(c > -0.005F)) {
        c = -0.005F;
      }

      bs_pre0 = er_mean + c;
    }

    bs_dif = bs_00 - bs_pre0;
    if ((bs_dif > 0.0F) && (bs_pre0 < bs)) {
      c = bs_00 - bs;
      if (!(c > 0.0F)) {
        c = 0.0F;
      }

      er_mean = bs_pre0 - bs;
      er_mean = 10.0F / (er_mean * er_mean);
      if (!(er_mean < 1.0F)) {
        er_mean = 1.0F;
      }

      bs_dif *= er_mean;
      if (!((bs_dif > c) || rtIsNaNF(c))) {
        bs_dif = c;
      }
    }

    if ((bs_dif < 0.0F) && (bs_pre0 > bs)) {
      c = bs_00 - bs;
      if (!(c < 0.0F)) {
        c = 0.0F;
      }

      er_mean = bs_pre0 - bs;
      er_mean = 6.0F / (er_mean * er_mean);
      if (!(er_mean < 1.0F)) {
        er_mean = 1.0F;
      }

      bs_dif *= er_mean;
      if (!((bs_dif < c) || rtIsNaNF(c))) {
        bs_dif = c;
      }
    }

    if (n > 720.0F) {
      if (countAfterCal < 230.0F) {
        bs_dif = 0.0F;
        bs_pre = bs_00;
      } else if ((caled > 0.0F) || (n > 1152.0F) || ((n > 864.0F) && (p1 <
                   -0.0015F))) {
        if ((er < 0.25F) || ((n > 1152.0F) && (er < 0.5F))) {
          if (rtIsNaNF(bs_0)) {
            bs_0 = bs_00;
          }

          bs_pre = bs_pre0;
        }
      } else {
        if ((value <= upper) && (value >= lower)) {
          bs_dif = 0.0F;
        }

        if (!rtIsNaNF(bs_pre)) {
          bs_pre = bs_pre0;
        }
      }
    } else {
      if (rtIsNaNF(bs_0)) {
        bs_dif = 0.0F;
      }
    }

    if (bs_dif > 0.0F) {
      c = bs_00 - lower;
      if (!(c < 0.2F)) {
        c = 0.2F;
      }

      if (!(c > 0.0F)) {
        c = 0.0F;
      }

      er_mean = c * 5.0F;
    } else {
      c = upper - bs_00;
      if (!(c < 0.2F)) {
        c = 0.2F;
      }

      if (!(c > 0.0F)) {
        c = 0.0F;
      }

      er_mean = c * 5.0F;
    }

    if (n > 432.0F) {
      if (!rtIsNaNF(bs_upper)) {
        bs_dif = bs_upper - bs_pre0;
        er_mean = 0.0F;
      }

      if (!rtIsNaNF(bs_lower)) {
        bs_dif = bs_lower - bs_pre0;
        er_mean = 0.0F;
      }
    }

    bs_dif *= 0.9F * er_mean + (1.0F - er_mean);
    if (bs_dif < 0.0F) {
      c = sg / 7.5F;
      if (!(c < 1.0F)) {
        c = 1.0F;
      }

      if (!(c > 0.0F)) {
        c = 0.0F;
      }

      bs_dif *= c;
      if (!(bs_dif < 0.0F)) {
        bs_dif = 0.0F;
      }

      /*  else */
      /*      pd = max(min((26-sg)/15, 1), 0); */
      /*      bs_dif = bs_dif * pd; */
      /*      bs_dif = max(bs_dif, 0); */
    }

    if ((bs_dif < 1.0F) && (bs_dif > -1.0F)) {
      f0 = bs_dif;
      b_sign(&f0);
      bs_dif = f0 * (bs_dif * bs_dif);
    }

    if ((bs_dif < minsg) || rtIsNaNF(minsg)) {
      b_bs_dif = bs_dif;
    } else {
      b_bs_dif = minsg;
    }

    *sg1 = sg + b_bs_dif;
    if (*sg1 < 2.0F) {
      buf_sg[287] = ((real32_T)rtNaN);
    }

    *b0 = bs_0;
    if (rtIsNaNF(bs_0)) {
      bs_pre = ((real32_T)rtNaN);
    }

    *bpre = bs_pre;

    /*  global b00 */
    /*  global b1 */
    /*  global b2 */
    /*  global er1 */
    /*  global ac */
    /*  global bc */
    /*  if n > 0 */
    /*      b00 = [b00;bs_0]; */
    /*      b1 = [b1;bs]; */
    /*      b2 = [b2;bs_next]; */
    /*      er1 = [er1;er]; */
    /*      ac = [ac; upper]; */
    /*      bc = [bc; lower]; */
    /*  end */
  }
}

/*
 * Arguments    : void
 * Return Type  : void
 */
void autobase_init(void)
{
  int i;
  autoRange = 0.0F;
  upper = 9.0F;
  lower = 4.0F;
  caled = 0.0F;
  countAfterCal = 0.0F;
  bs_0 = ((real32_T)rtNaN);
  bs_pre = ((real32_T)rtNaN);
  for (i = 0; i < 288; i++) {
    buf_sg[i] = ((real32_T)rtNaN);
  }

  for (i = 0; i < 432; i++) {
    buf_bs[i] = ((real32_T)rtNaN);
  }

  for (i = 0; i < 216; i++) {
    buf_er[i] = ((real32_T)rtNaN);
  }

  for (i = 0; i < 24; i++) {
    buf_auc[i] = ((real32_T)rtNaN);
  }
}

/*
 * File trailer for autobase.c
 *
 * [EOF]
 */
